/* NB. prev_p passed in %eax, next_p passed in %edx */
void __switch_to(struct task_struct *prev_p, struct task_struct *next_p)
{
- extern struct desc_struct idt_table[];
struct thread_struct *prev = &prev_p->thread,
*next = &next_p->thread;
struct tss_struct *tss = init_tss + smp_processor_id();
*/
int __init start_secondary(void *unused)
{
+ unsigned int cpu = smp_processor_id();
+ /* A 'mem64' suitable for passing to LIDT instruction. */
+ unsigned long idt_load[2] = { (IDT_ENTRIES*8)-1, 0 };
+
extern void cpu_init(void);
/*
while (!atomic_read(&smp_commenced))
rep_nop();
+ /*
+ * At this point, boot CPU has fully initialised the IDT. It is
+ * now safe to make ourselves a private copy.
+ */
+ idt_tables[cpu] = kmalloc(IDT_ENTRIES*8, GFP_KERNEL);
+ memcpy(idt_tables[cpu], idt_table, IDT_ENTRIES*8);
+ idt_load[2] = (unsigned long)idt_tables[cpu];
+ __asm__ __volatile__ ( "lidt %0" : "=m" (idt_load) );
+
/*
* low-memory mappings have been cleared, flush them from the local TLBs
* too.
asmlinkage void lcall7(void);
asmlinkage void lcall27(void);
-/*
- * The IDT has to be page-aligned to simplify the Pentium
- * F0 0F bug workaround.. We have a special link segment
- * for this.
- */
-struct desc_struct idt_table[256] __attribute__((__section__(".data.idt"))) = { {0, 0}, };
+/* Master table, and the one used by CPU0. */
+struct desc_struct idt_table[256] = { {0, 0}, };
+/* All other CPUs have their own copy. */
+struct desc_struct *idt_tables[NR_CPUS] = { 0 };
asmlinkage void divide_error(void);
asmlinkage void debug(void);
ti = current->thread.traps + (error_code>>3);
if ( ti->dpl >= (regs->xcs & 3) )
{
- if ( (error_code>>3)==0x80 ) { printk("!!!\n"); BUG(); }
+ /* XXX Kill next conditional soon :-) XXX */
+ if ( (error_code>>3)==0x80 )
+ {
+ printk("DIDN'T USE FAST-TRAP HANDLER FOR 0x80!!! :-(\n");
+ BUG();
+ }
gtb->flags = GTBF_TRAP_NOCODE;
gtb->cs = ti->cs;
gtb->eip = ti->address;
/* Only ring 1 can access monitor services. */
_set_gate(idt_table+HYPERVISOR_CALL_VECTOR,15,1,&hypervisor_call);
+ /* CPU0 uses the master IDT. */
+ idt_tables[0] = idt_table;
+
/*
* Should be a barrier for any external CPU state.
*/
trap_info_t traps[256];
};
+#define IDT_ENTRIES 256
+extern struct desc_struct idt_table[];
+extern struct desc_struct *idt_tables[];
+
#define SET_DEFAULT_FAST_TRAP(_p) \
(_p)->fast_trap_idx = 0x20; \
(_p)->fast_trap_desc.a = 0; \
(_p)->fast_trap_desc.b = 0;
#define CLEAR_FAST_TRAP(_p) \
- (memset(idt_table + (_p)->fast_trap_idx, 0, 8))
+ (memset(idt_tables[smp_processor_id()] + (_p)->fast_trap_idx, \
+ 0, 8))
#define SET_FAST_TRAP(_p) \
- (memcpy(idt_table + (_p)->fast_trap_idx, &((_p)->fast_trap_desc), 8))
+ (memcpy(idt_tables[smp_processor_id()] + (_p)->fast_trap_idx, \
+ &((_p)->fast_trap_desc), 8))
#define INIT_THREAD { \
sizeof(idle0_stack) + (long) &idle0_stack, /* esp0 */ \